using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FytSoa.Common;
using FytSoa.Core.Model;
using FytSoa.Extensions;
using FytSoa.Service.DtoModel;
using FytSoa.Service.Interfaces;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using FytSoa.Core.Model.Member;
using FytSoa.Core.Model.Cms;
using FytSoa.Core.Model.TourGuide;
using FytSoa.Extensions.Xcx;
using Newtonsoft.Json;

namespace FytSoa.Api.Controllers.App
{
    [Route("api/app/[controller]/[action]")]
    [ApiController]
    public class IndexController : ControllerBase
    {
        private readonly ICmsArticleService _articleService;
        private readonly ICmsAdvListService _advService;
        private readonly ICmsColumnService _columnService;
        private readonly IMemberService _memberService;
        private readonly ITourGuideOrderService _orderService;
        public IndexController(IMemberService memberService
        , ICmsArticleService articleService
            , ICmsAdvListService advService
            , ICmsColumnService columnService
        , ITourGuideOrderService orderService)
        {
            _memberService = memberService;
            _columnService = columnService;
            this._articleService = articleService;
            this._advService = advService;
            _orderService = orderService;
        }

        /// <summary>
        /// 查询订单列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<Page<TourGuideOrder>>> OrderList([FromBody]PageParm param)
        {
            return await _orderService.GetPageWhereList(param);
        }

        /// <summary>
        /// 申请退款
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> ApplyBack([FromBody]TourGuideOrder model)
        {
            var res = new ApiResult<string>() { statusCode = 500 };
            var istype = 1;    //1=到达  2=起飞
            DateTime tempDate = model.LandTime;
            //判断类型
            switch (model.Mold)
            {
                case 2: istype = 2; tempDate = model.TakeOffTime; break;
                case 4: istype = 2; tempDate = model.TakeOffTime; break;
                case 6: istype = 2; tempDate = model.TakeOffTime; break;
                case 7: istype = 2; tempDate = model.TakeOffTime; break;
                case 8: istype = 2; tempDate = model.TakeOffTime; break;
            }
            int compNum = DateTime.Compare(tempDate, DateTime.Now);
            if (compNum > 0 && (tempDate - DateTime.Now).TotalHours > 2.5)
            {
                model.BackStatus = 1;
                model.BackProgress.Add(new ServiceBackProgress() { info = "会员提出退款申请", times = DateTime.Now });
                //允许退款
                res = await _orderService.UpdateAsync(model);
            }
            else
            {
                res.message = "已超过退款时间，不允许退款~";
            }
            return res;
        }

        double GetTimes(DateTime dt)
        {
            var h = Convert.ToString(dt.Hour > 9 ? dt.Hour : '0' + dt.Hour);
            var m = Convert.ToString(dt.Minute > 9 ? dt.Minute : '0' + dt.Minute);
            return Convert.ToDouble(h + m);
        }

        /// <summary>
        /// 添加新的服务订单
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<TourGuideOrderSuccessDto>> AddOrder([FromBody]TourGuideOrder model)
        {
            var res = new ApiResult<TourGuideOrderSuccessDto>();

            //判断用户可用性
            var userModel = await _memberService.GetModelAsync(m => m.Guid == model.MemberGuid && m.Status && !m.IsDel);
            if (string.IsNullOrEmpty(userModel.data.Guid))
            {
                res.statusCode = 500;
                res.message = "用户不存在、或账号被冻结~";
                return res;
            }
            //Logger.Default.Info(JsonConvert.SerializeObject(model));
            //Logger.Default.Info(model.ServiceData + " " + model.LandTime);
            model.Guid = Guid.NewGuid().ToString();
            model.Number = Utils.GetOrderNumber();
            if (!string.IsNullOrEmpty(model.ddtime))
            {
                model.LandTime = Convert.ToDateTime(model.ddtime);
            }
            if (!string.IsNullOrEmpty(model.qftime))
            {
                model.TakeOffTime = Convert.ToDateTime(model.qftime);
            }
            var dbres = await _orderService.AddAsync(model);
            if (dbres.statusCode == 200)
            {
                res.data = new TourGuideOrderSuccessDto()
                {
                    number = model.Number,
                    userGuid = model.MemberGuid,
                    orderGuid = model.Guid
                };
            }
            return res;
        }

        /// <summary>
        /// 修改订单成功状态
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> PayStatus([FromBody]ParmString param)
        {
            var model = await _orderService.GetModelAsync(m => m.Number == param.parm);
            if (model.data.PayStatus) return new ApiResult<string>();
            model.data.PayStatus = true;
            return await _orderService.UpdateAsync(model.data);
        }

        /// <summary>
        /// 首页返回公告和广告图
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<List<CmsAdvList>>> Init()
        {
            return await _advService.GetListAsync(m => m.ClassGuid == "e8b4325d-bdd8-448f-83be-034d66642b14" && m.Status, m => m.Sort, DbOrderEnum.Desc);
        }

        /// <summary>
        /// 查询系统公告列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<Page<CmsArticle>>> ArticleList([FromBody]PageParm param)
        {
            return await _articleService.GetPagesAsync(param,
            m => m.ColumnId == 1029 && m.Audit && !m.IsRecyc, m => m.EditDate, DbOrderEnum.Desc);
        }

        /// <summary>
        /// 查询系统公告列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<List<CmsArticle>>> Question()
        {
            return await _articleService.GetListAsync(
            m => m.ColumnId == 1031 && m.Audit && !m.IsRecyc, m => m.EditDate, DbOrderEnum.Desc);
        }

        /// <summary>
        /// 查询系统公告的详情
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<CmsArticle>> Article([FromBody]ParmInt param)
        {
            return await _articleService.GetModelAsync(m => m.Id == param.id);
        }

        /// <summary>
        /// 查询系统公告的详情
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<CmsColumn>> About()
        {
            return await _columnService.GetModelAsync(m => m.Id == 1030);
        }

        #region 用户信息
        /// <summary>
        /// APP登录
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<Core.Model.Member.Member>> Login([FromBody]AppLoginParam param)
        {
            return await _memberService.Login(param);
        }

        /// <summary>
        /// 修改姓名
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> Update([FromBody]Core.Model.Member.Member param)
        {
            return await _memberService.UpdateAsync(param);
        }

        /// <summary>
        /// APP注册
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<string>> Reg([FromBody]Core.Model.Member.Member param)
        {
            param.Guid = Guid.NewGuid().ToString();
            param.Grade = "1fc19833-539a-40cf-a000-1f9037b8dae4";
            param.HeadPic = "/themes/img/avatar.jpg";
            return await _memberService.Add(param);
        }

        /// <summary>
        /// 发送验证码
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> SendCode([FromBody]SendCodeParam model)
        {
            var tempId = "";
            //如果是注册，判断手机号码是否存在
            if (model.types == 1)
            {
                tempId = "SMS_178756747";
                //判断手机号码是否存在
                var isu = await _memberService.IsExistAsync(m => m.Mobile == model.mobile && !m.IsDel);
                if (isu.data.Any)
                {
                    return Ok(new ApiResult<string>()
                    {
                        statusCode = 500,
                        message = "手机号码已注册，请更换！"
                    });
                }
            }
            else
            {
                tempId = "SMS_178766746";
            }
            var code = Utils.Number(6);
            var resSsm = AliSsmTool.SendSsm(new AliSsmParam()
            {
                phone = model.mobile,
                code = code,
                tempId = tempId
            });
            var res = new ApiResult<string>() { data = code };
            if (resSsm.Code != "OK")
            {
                res.statusCode = 500;
                res.message = resSsm.Message;
            }
            return Ok(res);
        }

        /// <summary>
        /// 找回密码
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<IActionResult> FindPwd([FromBody]FindPwdParam model)
        {
            var res = new ApiResult<string>();
            //根据手机号码查询用户
            var user = await _memberService.GetModelAsync(m => m.Mobile == model.mobile && !m.IsDel);
            if (user.data != null && !string.IsNullOrEmpty(user.data.Guid))
            {
                //设置新的密码
                user.data.LoginPwd = DES3Encrypt.EncryptString(model.pwd);
                //更新用户信息
                res = await _memberService.UpdateAsync(user.data);
            }
            else
            {
                res.message = "用户不存在";
                res.statusCode = 404;
            }
            return Ok(res);
        }
        #endregion


        /// <summary>
        /// 提交订单支付
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<TourGuidePayDto>> XcxPay([FromBody]TourGuidePayParam param)
        {
            var res = new ApiResult<TourGuidePayDto>() { statusCode = 500 };
            try
            {
                //订单描述
                #region 统一下单
                XcxPayData data = new XcxPayData();
                data.SetValue("body", "TourGuideBuy");

                //可以将用户Id和订单Id同时封装在attach中
                data.SetValue("attach", param.orderGuid);
                data.SetValue("out_trade_no", param.number);
                data.SetValue("detail", "");
                data.SetValue("total_fee", Convert.ToInt32(param.price * 100));
                data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));
                data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));
                data.SetValue("notify_url", XcxPayConfig.NOTIFY_URL);
                //data.SetValue("goods_tag", "test");
                data.SetValue("trade_type", "JSAPI");
                data.SetValue("openid", XcxHelper.Code2Session(param.code).openid);
                Logger.Default.Debug("Index下单前请求参数：" + data.ToJson());
                XcxPayData result = XcxPayApi.UnifiedOrder(data);
                Logger.Default.Info("Index下单返回结果：" + result.ToJson());
                var flag = true;
                var msg = "";
                var nonceStr = "";
                var appId = "";
                var package = "";
                var mch_id = "";
                if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")
                {
                    res.message = "下单失败！";
                    return res;
                }
                else
                {
                    //统一下单  -- 修改订单状态
                    nonceStr = result.GetValue("nonce_str").ToString();
                    appId = result.GetValue("appid").ToString();
                    mch_id = result.GetValue("mch_id").ToString();
                    package = "prepay_id=" + result.GetValue("prepay_id").ToString();
                }
                var signType = "MD5";
                var timeStamp = ((DateTime.Now.Ticks - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)).Ticks) / 10000).ToString();
                XcxPayData applet = new XcxPayData();
                applet.SetValue("appId", appId);
                applet.SetValue("nonceStr", nonceStr);
                applet.SetValue("package", package);
                applet.SetValue("signType", signType);
                applet.SetValue("timeStamp", timeStamp);
                var appletSign = applet.MakeSign();
                res.data = new TourGuidePayDto()
                {
                    timeStamp = timeStamp,
                    nonceStr = nonceStr,
                    package = package,
                    signType = signType,
                    paySign = appletSign
                };
                res.statusCode = 200;
                //return Json(new { timeStamp, nonceStr, package, signType, paySign = appletSign, Result = flag, msg });

                #endregion
            }
            catch (System.Exception ex)
            {
                res.message = ex.Message;
            }
            return res;
        }

        [HttpGet]
        public async Task<string> XcxPayNotifyUrl()
        {
            try
            {
                XcxPayNotify notify = new XcxPayNotify(HttpContext);
                XcxPayData notifyData = notify.GetNotifyData();

                //检查支付结果中transaction_id是否存在
                if (!notifyData.IsSet("transaction_id"))
                {
                    //若transaction_id不存在，则立即返回结果给微信支付后台
                    XcxPayData res = new XcxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "支付结果中微信订单号不存在");
                    Logger.Default.Debug("支付结果中微信订单号不存在");
                    return res.ToXml();
                }

                string transaction_id = notifyData.GetValue("transaction_id").ToString();

                //查询订单，判断订单真实性
                if (!XcxQueryOrder(transaction_id))
                {
                    //若订单查询失败，则立即返回结果给微信支付后台
                    XcxPayData res = new XcxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "订单查询失败");
                    Logger.Default.Debug("订单查询失败");
                    return res.ToXml();
                }
                //查询订单成功
                else
                {
                    XcxPayData res = new XcxPayData();
                    res.SetValue("return_code", "SUCCESS");
                    res.SetValue("return_msg", "OK");
                    Logger.Default.Debug("SUCCESS");

                    var returnCode = notifyData.GetValue("return_code").ToString();
                    var transactionNo = transaction_id;//微信订单号
                    var outTradeNo = notifyData.GetValue("out_trade_no").ToString();//自定义订单号
                    var attach = notifyData.GetValue("attach").ToString();//身份证
                    var endTime = notifyData.GetValue("time_end").ToString();//交易结束时间
                                                                             //var body = notifyData.GetValue("body").ToString();//projectIdlist
                    var totalFee = notifyData.GetValue("total_fee").ToString(); ;//支付金额

                    //int userId = Convert.ToInt32(attach.Split('|')[0]);

                    //根据订单号修改支付状态
                    Logger.Default.Info("支付成功回调：" + notifyData.ToJson());

                    if (!string.IsNullOrEmpty(outTradeNo))
                    {
                        var model = await _orderService.GetModelAsync(m => m.Number == outTradeNo);
                        if (!model.data.PayStatus)
                        {
                            model.data.PayStatus = true;
                            await _orderService.UpdateAsync(model.data);
                        }
                    }

                    return res.ToXml();
                }
            }
            catch (System.Exception ex)
            {
                Logger.Default.Info("支付成功异常：" + ex.Message);
            }
            return "";
        }

        /// <summary>
        /// 查询订单
        /// </summary>
        /// <param name="transaction_id">微信交易订单号</param>
        /// <returns></returns>
        private bool XcxQueryOrder(string transaction_id)
        {
            XcxPayData req = new XcxPayData();
            req.SetValue("transaction_id", transaction_id);
            XcxPayData res = XcxPayApi.OrderQuery(req);
            if (res.GetValue("return_code").ToString() == "SUCCESS" && res.GetValue("result_code").ToString() == "SUCCESS")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
